import pandas as pd
import math
import matplotlib.pyplot as plt  # 导入绘图模块
import random

# 读取数据
df = pd.read_csv(r"C:\Users\lenovo\Downloads\linear_regression_data_1000.csv", encoding="utf-8")

def Normalization():
    max_x = df["X"].max()
    min_x = df["X"].min()
    max_y = df["Y"].max()
    min_y = df["Y"].min()

    for i in range(0,df["X"].count()):
        df["X"][i] = (df["X"][i]-min_x)/(max_x-min_x)
        df["Y"][i] = (df["Y"][i] - min_y) / (max_y - min_y)

def Normalization():
    max_x = df["X"].max()
    min_x = df["X"].min()
    max_y = df["Y"].max()
    min_y = df["Y"].min()

    for i in range(0,df["X"].count()):
        df["X"][i] = (df["X"][i]-min_x)/(max_x-min_x)
        df["Y"][i] = (df["Y"][i] - min_y) / (max_y - min_y)



# 定义模型
def model(w, b, x):
    return w * x + b


# 成本函数
def cost_function(w, b):
    m = df['X'].count()
    total_cost = 0.0
    for i in range(m):
        total_cost += math.pow(model(w, b, df['X'][i]) - df['Y'][i], 2)
    return (1.0 / (2 * m)) * total_cost


# 对 w 求导数的部分
def cost_function_w(w, b):
    m = df['X'].count()
    total_w = 0.0
    for i in range(m):
        total_w += (model(w, b, df['X'][i]) - df['Y'][i]) * df['X'][i]
    return (1.0 / m) * total_w


# 对 b 求导数的部分
def cost_function_b(w, b):
    m = df['X'].count()
    total_b = 0.0
    for i in range(m):
        total_b += (model(w, b, df['X'][i]) - df['Y'][i])
    return (1.0 / m) * total_b


# 绘图函数
def plot_regression_line(df, w, b):
    # 绘制数据点
    plt.scatter(df['X'], df['Y'], color='blue', label='Data Points')

    # 画出拟合直线
    x_range = [min(df['X']), max(df['X'])]
    y_range = [model(w, b, x) for x in x_range]
    plt.plot(x_range, y_range, color='red', label=f"Fitted Line: y = {w:.2f}x + {b:.2f}")

    # 添加标签和标题
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.title('Linear Regression Fit')
    plt.legend()

    # 显示图形
    plt.show()
if __name__ == "__main__":
    # 初始化参数
    w = random.uniform(-1, 1)  # 随机初始化
    b = random.uniform(-1, 1)  # 随机初始化
    rate = 0.0005  # 学习率
    threshold = 0.001  # 终止条件阈值
    min_cost = float('inf')  # 初始设定一个非常大的 cost 值
    max_iterations = 1000000  # 最大迭代次数，防止死循环
    iteration = 0

    # 梯度下降
    while iteration < max_iterations:
        new_cost = cost_function(w, b)

        # 判断是否满足收敛条件
        if math.fabs(min_cost - new_cost) < threshold:
            print(f"收敛！迭代次数：{iteration}, 最小代价：{min_cost}")
            break

        # 更新 w 和 b
        w = w - rate * cost_function_w(w, b)
        b = b - rate * cost_function_b(w, b)

        # 更新最小代价
        min_cost = new_cost

        iteration += 1

    if iteration == max_iterations:
        print("达到最大迭代次数，尚未收敛。")


    # 调用绘图函数
    plot_regression_line(df, w, b)
    plot_regression_line(df, 3.70576, 0.354824)
